/*
 * Teknei 2014 - All rights reserved
 */
package com.teknei.acabus.core.services.impl;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import com.teknei.acabus.PersistenceException;
import com.teknei.acabus.ServiceException;
import com.teknei.acabus.core.entities.NavigationChild;
import com.teknei.acabus.core.entities.NavigationChildRole;
import com.teknei.acabus.core.entities.NavigationParent;
import com.teknei.acabus.core.entities.NavigationParentRole;
import com.teknei.acabus.core.entities.Role;
import com.teknei.acabus.core.persistence.dao.NavigationDAO;
import com.teknei.acabus.core.persistence.dao.NavigationRolesDAO;
import com.teknei.acabus.core.persistence.dao.RolesDAO;
import com.teknei.acabus.core.services.NavigationRolesService;

/**
 * Session Bean implementation class NavigationRolesServiceBean
 * @author Jorge Amaro
 * @version 1.0
 * @since 1.0
 */
@Stateless
public class NavigationRolesServiceBean implements NavigationRolesService {

	@EJB
	private NavigationRolesDAO daoRolesNavigation;
	
	@EJB
	private RolesDAO daoRoles;
	
	@EJB
	private NavigationDAO daoNavigation;
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#saveNavigationParent(com.teknei.acabus.core.entities.NavigationParent)
	 */
	@Override
	public int saveNavigationParent(NavigationParent parent) throws ServiceException{
		try{
			NavigationParent entity = daoNavigation.createNavigationParent(parent);
			int pk = entity.getIdParent();
			return pk;
		}catch(PersistenceException e){
			throw new ServiceException("Error in saveNavigationParent:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#saveNavigationChild(com.teknei.acabus.core.entities.NavigationChild)
	 */
	@Override
	public int saveNavigationChild(NavigationChild child) throws ServiceException{
		try{
			NavigationChild entity = daoNavigation.createNavigationChild(child);
			int pk = entity.getIdChild();
			return pk;
		}catch(PersistenceException e){
			throw new ServiceException("Error in saveNavigationChild:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#updateNavigationChild(com.teknei.acabus.core.entities.NavigationChild)
	 */
	@Override
	public void updateNavigationChild(NavigationChild child) throws ServiceException{
		try{
			daoNavigation.updateNavigationChild(child);
		}catch(PersistenceException e){
			throw new ServiceException("Error in updateNavigationChild:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#updateNavigationParent(com.teknei.acabus.core.entities.NavigationParent)
	 */
	@Override
	public void updateNavigationParent(NavigationParent parent) throws ServiceException{
		try{
			daoNavigation.updateNavigationParent(parent);
		}catch(PersistenceException e){
			throw new ServiceException("Error in updateNavigationParent:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#updateNavigationParentWithRoles(com.teknei.acabus.core.entities.NavigationParent)
	 */
	@Override
	public void updateNavigationParentWithRoles(NavigationParent parent) throws ServiceException{
		try{
			daoNavigation.updateNavigationParentWithRoles(parent);
		}catch(PersistenceException e){
			throw new ServiceException("Error in updateNavigationParent:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#updateNavigationChildWithRoles(com.teknei.acabus.core.entities.NavigationChild)
	 */
	@Override
	public void updateNavigationChildWithRoles(NavigationChild child) throws ServiceException{
		try{
			daoNavigation.updateNavigationChildWithRoles(child);
		}catch(PersistenceException e){
			throw new ServiceException("Error in updateNavigationChildWithRoles:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#deleteNavigationParent(com.teknei.acabus.core.entities.NavigationParent)
	 */
	@Override
	public void deleteNavigationParent(NavigationParent parent) throws ServiceException{
		try{
			daoNavigation.deleteNavigationParent(parent);
		}catch(PersistenceException e){
			throw new ServiceException("Error in deleteNavigationParent:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#deleteNavigationChild(com.teknei.acabus.core.entities.NavigationChild)
	 */
	@Override
	public void deleteNavigationChild(NavigationChild child) throws ServiceException{
		try{
			daoNavigation.deleteNavigationChild(child);
		}catch(PersistenceException e){
			throw new ServiceException("Error in deleteNavigationChild:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#saveRole(com.teknei.acabus.core.entities.Role)
	 */
	@Override
	public int saveRole(Role role) throws ServiceException{
		try{
			Role entity = daoRoles.create(role);
			int id = entity.getIdRole();
			return id;
		}catch(PersistenceException e){
			throw new ServiceException("Error in saveRole:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#updateRole(com.teknei.acabus.core.entities.Role)
	 */
	@Override
	public void updateRole(Role role) throws ServiceException{
		try{
			daoRoles.update(role);
		}catch(PersistenceException e){
			throw new ServiceException("Error in updateRole:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#deleteRole(com.teknei.acabus.core.entities.Role)
	 */
	@Override
	public void deleteRole(Role role) throws ServiceException{
		try{
			daoRoles.delete(role);
		}catch(PersistenceException e){
			throw new ServiceException("Error in deleteRole:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#findRoles()
	 */
	@Override
	public List<Role> findRoles() throws ServiceException{
		try{
			List<Role> list = daoRoles.findAll();
			return list;
		}catch(PersistenceException e){
			throw new ServiceException("Error in findRoles:"+e.getMessage(), e);
		}
	}
	
	/**
	 * Finds the navigation children related based also on the role
	 * @param role
	 * @param parent
	 * @return
	 * @throws PersistenceException
	 */
	private List<NavigationChild> findNavigationChildsByRole(Role role, NavigationParent parent) throws PersistenceException{
		List<NavigationChild> listChilds = new LinkedList<NavigationChild>(); 
		List<NavigationChildRole> listChildsRoles = daoRolesNavigation.findNavigationChildRoles();
		for(NavigationChildRole chrole : listChildsRoles){
			if(chrole.getChild().getNavigationParent().getIdParent().equals(parent.getIdParent()) && chrole.getRole().getIdRole().equals(role.getIdRole())){
				listChilds.add(chrole.getChild());
			}
		}
		return listChilds;
	}
	
	/**
	 * Finds the navigation parent items based on the role
	 * @param role
	 * @return
	 * @throws PersistenceException
	 */
	private List<NavigationParent> findNavigationParentsByRole(Role role) throws PersistenceException{
			List<NavigationParentRole> list = daoRolesNavigation.findNavigationParentRoles();
			List<NavigationParent> listParents = new LinkedList<NavigationParent>();
			for(NavigationParentRole parent : list){
				if(parent.getRole().getIdRole().equals(role.getIdRole())){
					listParents.add(parent.getParent());
				}
			}
			return listParents;
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#findNavigationChildsByRoles(java.util.List, com.teknei.acabus.core.entities.NavigationParent)
	 */
	@Override
	public List<NavigationChild> findNavigationChildsByRoles(List<Role> roles, NavigationParent parent) throws ServiceException{
		try{
			Set<NavigationChild> setChilds = new HashSet<NavigationChild>();
			List<NavigationChild> list = new LinkedList<NavigationChild>();
			for(Role role : roles){
				list.addAll(findNavigationChildsByRole(role, parent));
			}
			setChilds.addAll(list);
			list = new LinkedList<NavigationChild>();
			list.addAll(setChilds);
			return list;
		}catch (PersistenceException e) {
			throw new ServiceException("Error in findNavigationParentsByRoles:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#findNavigationParentsByRoles(java.util.List)
	 */
	@Override
	public List<NavigationParent> findNavigationParentsByRoles(List<Role> roles) throws ServiceException{
		try{
			Set<NavigationParent> setParents = new HashSet<NavigationParent>();
			List<NavigationParent> list = new LinkedList<NavigationParent>();
			for(Role role : roles){
				list.addAll(findNavigationParentsByRole(role));
			}
			setParents.addAll(list);
			list = new LinkedList<NavigationParent>();
			list.addAll(setParents);
			return list;
		}catch (PersistenceException e) {
			throw new ServiceException("Error in findNavigationParentsByRoles:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#findRolesAllowed(com.teknei.acabus.core.entities.NavigationParent)
	 */
	@Override
	public List<Role> findRolesAllowed(NavigationParent element) throws ServiceException{
		try {
			List<NavigationParentRole> list = daoRolesNavigation.findNavigationParentRoles();
			List<Role> listRoles = new LinkedList<Role>();
			for(NavigationParentRole parent : list){
				if(parent.getParent().getIdParent().equals(element.getIdParent())){
					listRoles.add(parent.getRole());
				}
			}
			return listRoles;
		} catch (PersistenceException e) {
			throw new ServiceException("Error in findRolesAllowed:"+e.getMessage(), e);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.teknei.acabus.core.services.NavigationRolesService#findRolesAllowed(com.teknei.acabus.core.entities.NavigationChild)
	 */
	@Override
	public List<Role> findRolesAllowed(NavigationChild element) throws ServiceException{
		try {
			List<NavigationChildRole> list = daoRolesNavigation.findNavigationChildRoles();
			List<Role> listRoles = new LinkedList<Role>();
			for(NavigationChildRole child : list){
				if(child.getChild().getIdChild().equals(element.getIdChild())){
					listRoles.add(child.getRole());
				}
			}
			return listRoles;
		} catch (PersistenceException e) {
			throw new ServiceException("Error in findRolesAllowed:"+e.getMessage(), e);
		}
		
	}

	/**
	 * @return the daoRolesNavigation
	 */
	public NavigationRolesDAO getDaoRolesNavigation() {
		return daoRolesNavigation;
	}

	/**
	 * @param daoRolesNavigation the daoRolesNavigation to set
	 */
	public void setDaoRolesNavigation(NavigationRolesDAO daoRolesNavigation) {
		this.daoRolesNavigation = daoRolesNavigation;
	}

	/**
	 * @return the daoRoles
	 */
	public RolesDAO getDaoRoles() {
		return daoRoles;
	}

	/**
	 * @param daoRoles the daoRoles to set
	 */
	public void setDaoRoles(RolesDAO daoRoles) {
		this.daoRoles = daoRoles;
	}

}
